#!/usr/local/bin/lua
-- 单行注释
print("Hello World！")

--[[
 多行注释
 测试项目

####################### 关键字 ####################### 
and	break	do	else
elseif	end	false	for
function	if	in	local
nil	not	or	repeat
return	then	true	until
while	goto

####################### 数据结构 ####################### 
nil	这个最简单，只有值nil属于该类，表示一个无效值（在条件表达式中相当于false）。
boolean	包含两个值：false和true。
number	表示双精度类型的实浮点数
string	字符串由一对双引号或单引号来表示
function	由 C 或 Lua 编写的函数
userdata	表示任意存储在变量中的C数据结构
thread	表示执行的独立线路，用于执行协同程序
table	Lua 中的表（table）其实是一个"关联数组"（associative arrays），
数组的索引可以是数字、字符串或表类型。在 Lua 里，
table 的创建是通过"构造表达式"来完成，最简单构造表达式是{}，用来创建一个空表。

    if false or nil then
        print("至少有一个是 true")
    else
        -- false 和 nil 都为 false
        print("false 和 nil 都为 false")
    end

    print(type("Hello world"))      --> string
    print(type(10.4*3))             --> number
    print(type(print))              --> function
    print(type(type))               --> function
    print(type(true))               --> boolean
    print(type(nil))                --> nil
    print(type(type(X)))            --> string
####################### 字符串 ####################### 
# 也可以用 2 个方括号 "[[/]/]" 来表示"一块"字符串。
    html = [[
    <html>
    <head></head>
    <body>
        <a href="http://www.runoob.com/">菜鸟教程</a>
    </body>
    </html>
    ]/]
    print(html)
字符串连接使用的是 ..
    > print("a" .. 'b')
    ab
    > print(157 .. 428)
    157428
使用 # 来计算字符串的长度，放在字符串前面，如下实例：
    > len = "www.runoob.com"
    > print(#len)
    14
    > print(#"www.runoob.com")
    14

####################### table（表） ####################### 
在 Lua 里，table 的创建是通过"构造表达式"来完成，最简单构造表达式是{}，用来创建一个空表。也可以在表里添加一些数据，直接初始化表:
    -- 创建一个空的 table
    local tbl1 = {}
    
    -- 直接初始表
    local tbl2 = {"apple", "pear", "orange", "grape"}
Lua 中的表（table）其实是一个"关联数组"（associative arrays），数组的索引可以是数字或者是字符串。
    -- table_test.lua 脚本文件
    a = {}
    a["key"] = "value"
    key = 10
    a[key] = 22
    a[key] = a[key] + 11
    for k, v in pairs(a) do
        print(k .. " : " .. v)
    end
不同于其他语言的数组把 0 作为数组的初始索引，在 Lua 里表的默认初始索引一般以 1 开始。
    -- table_test2.lua 脚本文件
    local tbl = {"apple", "pear", "orange", "grape"}
    for key, val in pairs(tbl) do
        print("Key", key)
    end
####################### function（函数） ####################### 
在 Lua 中，函数是被看作是"第一类值（First-Class Value）"，函数可以存在变量里:
    -- function_test.lua 脚本文件
    function factorial1(n)
        if n == 0 then
            return 1
        else
            return n * factorial1(n - 1)
        end
    end
    print(factorial1(5))
    factorial2 = factorial1
    print(factorial2(5))

function 可以以匿名函数（anonymous function）的方式通过参数传递:
    -- function_test2.lua 脚本文件
    function testFun(tab,fun)
            for k ,v in pairs(tab) do
                    print(fun(k,v));
            end
    end


    tab={key1="val1",key2="val2"};
    testFun(tab,
    function(key,val)--匿名函数
            return key.."="..val;
    end
    );
####################### thread（线程） ####################### 
    在 Lua 里，最主要的线程是协同程序（coroutine）。它跟线程（thread）差不多，拥有自己独立的栈、局部变量和指令指针，可以跟其他协同程序共享全局变量和其他大部分东西。

    线程跟协程的区别：线程可以同时多个运行，而协程任意时刻只能运行一个，并且处于运行状态的协程只有被挂起（suspend）时才会暂停。

####################### userdata（自定义类型） ####################### 
    userdata 是一种用户自定义数据，用于表示一种由应用程序或 C/C++ 语言库所创建的类型，可以将任意 C/C++ 的任意数据类型的数据（通常是 struct 和 指针）存储到 Lua 变量中调用。
####################### 变量 ####################### 
    local b = 5         -- 局部变量
    若不加local，可以作为全局变量
    当变量个数和值的个数不一致时，Lua会一直以变量个数为基础采取以下策略：
        a. 变量个数 > 值的个数             按变量个数补足nil
        b. 变量个数 < 值的个数             多余的值会被忽略

    a, b, c = 0, 1
    print(a,b,c)             --> 0   1   nil
    
    a, b = a+1, b+1, b+2     -- value of b+2 is ignored
    print(a,b)               --> 1   2
    
    a, b, c = 0
    print(a,b,c)             --> 0   nil   nil
上面最后一个例子是一个常见的错误情况，注意：如果要对多个变量赋值必须依次对每个变量赋值。
对 table 的索引使用方括号 []。Lua 也提供了 . 操作。
    t[i]
    t.i                 -- 当索引为字符串类型时的一种简化写法
    gettable_event(t,i) -- 采用索引访问本质上是一个类似这样的函数调用

    > site = {}
    > site["key"] = "www.runoob.com"
    > print(site["key"])
    www.runoob.com
    > print(site.key)
    www.runoob.com

####################### 循环 ####################### 
while 循环	在条件为 true 时，让程序重复地执行某些语句。执行语句前会先检查条件是否为 true。
for 循环	重复执行指定语句，重复次数可在 for 语句中控制。
repeat...until	重复执行循环，直到 指定的条件为真时为止
循环嵌套	可以在循环内嵌套一个或多个循环语句（while do ... end;for ... do ... end;repeat ... until;）
break 语句	退出当前循环或语句，并开始脚本执行紧接着的语句。
goto 语句	将程序的控制点转移到一个标签处。
############################################################################################ 
多返回值 Lua函数可以返回多个结果值，比如string.find，其返回匹配串"开始和结束的下标"（如果不存在匹配串返回nil）。
    > s, e = string.find("www.runoob.com", "runoob") 
    > print(s, e)
 5    10
可变参数
Lua 函数可以接受可变数目的参数，和 C 语言类似，在函数参数列表中使用三点 ... 表示函数有可变的参数。
    function add(...)  
    local s = 0  
    for i, v in ipairs{...} do   --> {...} 表示一个由所有变长参数构成的数组  
        s = s + v  
    end  
    return s  
    end  
    print(add(3,4,5,6,7))  --->25
我们可以将可变参数赋值给一个变量。

例如，我们计算几个数的平均值：
    function average(...)
    result = 0
    local arg={...}    --> arg 为一个表，局部变量
    for i,v in ipairs(arg) do
        result = result + v
    end
    print("总共传入 " .. #arg .. " 个数")
    return result/#arg
    end

    print("平均值为",average(10,5,3,4,5,6))
 --]]
print("---------------------------------函数调用------------------------------------------")
-- 函数返回两个值的最大值
function max(num1, num2)

    if (num1 > num2) then
        result = num1;
    else
        result = num2;
    end

    return result;
end
-- 调用函数
print("两值比较最大值为 ",max(10,4))
print("两值比较最大值为 ",max(5,6))
print("-------------------------------------------")
function factorial1(n)
    if n == 0 then
        return 1
    else
        return n * factorial1(n - 1)
    end
end
print(factorial1(0))
factorial2 = factorial1
print(factorial2(5))
print("-------------------------------------------")
function maximum (a)
    local mi = 1             -- 最大值索引
    local m = a[mi]          -- 最大值
    for i,val in ipairs(a) do
       if val > m then
           mi = i
           m = val
       end
    end
    return m, mi
end

print(maximum({8,10,23,12,5}))
print("------------------------------函数调用结束---------------------------------------------")







